import com.sun.org.apache.bcel.internal.generic.Select;

import java.io.IOException;

import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.*;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class Main {
    public static int port = 80;
    public static void main(String[] args) {
       byte[] rotation = new byte[95*2];
       for(byte i = ' '; i <= '~'; i++) {
           rotation[i - ' '] = i;
           rotation[i + 95 - ' '] = i;
       }

       ServerSocketChannel serverSocketChannel;
       Selector selector;
       try {
           serverSocketChannel = ServerSocketChannel.open();
           serverSocketChannel.bind(new InetSocketAddress(port));
           serverSocketChannel.configureBlocking(false);
           selector = Selector.open();
           serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

       }catch(IOException e) {return;}

       while(true) {
           try{
               selector.select();
           } catch(IOException e) {
               e.printStackTrace();
               break;
           }
       }
        Set<SelectionKey> readKeys = selector.selectedKeys();
        Iterator<SelectionKey> iterator = readKeys.iterator();
        while(iterator.hasNext()) {
            SelectionKey key = iterator.next();
            iterator.remove();
            try{
                if(key.isAcceptable()) {
                    ServerSocketChannel server = (ServerSocketChannel)key.channel();
                    SocketChannel client = server.accept();
                    System.out.println("Accept connection" + client);
                    client.configureBlocking(false);
                    SelectionKey key1 = client.register(selector, SelectionKey.OP_WRITE);
                    ByteBuffer byteBuffer = ByteBuffer.allocate(74);
                    byteBuffer.put(rotation, 0, 72);
                    byteBuffer.put((byte) '\r');
                    byteBuffer.put((byte) '\n');
                    byteBuffer.flip();
                    key1.attach(byteBuffer);
                } else if(key.isWritable()) {
                    SocketChannel client = (SocketChannel)key.channel();
                    ByteBuffer buffer = (ByteBuffer) key.attachment();
                    if(!buffer.hasRemaining()) {
                        buffer.rewind();
                        int first = buffer.get();
                        buffer.rewind();
                        int positon = first - ' ' + 1;
                        buffer.put(rotation, positon, 72);
                        buffer.put((byte) '\r');
                        buffer.put((byte) '\n');
                        buffer.flip();
                    }
                    client.write(buffer);
                }
            } catch(IOException e) {
                key.channel();
                try{
                    key.channel().close();
                } catch(IOException e1) {
                    e1.printStackTrace();
                }
            }
        }

    }


}
